<template>
  <el-form-item v-if="config.type!=='object'" v-show="getShow(config.show)" :style="{width: width}" :class="['ml-form-'+config.type,{'mlform-item-block': config.block}]" :label="config.label" :required="required" :error="error" :validate-status="validateStatus" class="mlform-item">
    <!-- 基本文本输入框 -->
    <el-input
      v-if="config.type==='string' || config.type==='phone' || config.type==='mail' || config.type==='bankCode' || config.type==='idCard' || config.type==='number'"
      v-bind="config.attribute"
      :placeholder="config.placeholder"
      :disabled="config.disabled"
      :readonly="config.readonly"
      :value="value"
      size="small"
      type="text"
      clearable
      @input="input"
      @blur="blur">
      <template v-if="config.prepend" slot="prepend">{{ config.prepend }}</template>
      <template v-if="config.append" slot="append">{{ config.append }}</template>
    </el-input>
    <!-- 密码 TODO 可点击查看文本 -->
    <el-input
      v-else-if="config.type==='password'"
      v-bind="config.attribute"
      :placeholder="config.placeholder"
      :disabled="config.disabled"
      :readonly="config.readonly"
      :value="value"
      size="small"
      type="password"
      clearable
      @input="input"
      @blur="blur"/>
    <!-- 文本域 -->
    <el-input
      v-else-if="config.type==='text'"
      v-bind="config.attribute"
      :rows="8"
      :placeholder="config.placeholder"
      :disabled="config.disabled"
      :readonly="config.readonly"
      :value="value"
      :max="config.max"
      class="text-input"
      type="textarea"
      clearable
      @input="input"
      @blur="blur"/>
    <!-- 开关 -->
    <el-switch v-else-if="config.type==='boolean'" v-bind="config.attribute" :value="value" :disabled="config.disabled" @input="input" @blur="blur"/>
    <!-- 下拉 -->
    <el-select v-else-if="config.type==='select'" v-bind="config.attribute" :multiple="config.multiple" :value="value" :placeholder="config.placeholder" :disabled="config.disabled" size="small" @input="input" @blur="blur">
      <el-option v-for="option in config.options" :key="option.value" :label="option.label" :value="option.value" :disabled="option.disabled"/>
    </el-select>
    <!-- 单选 -->
    <template v-else-if="config.type==='radio'">
      <el-radio v-for="option in config.options" v-bind="config.attribute" :disabled="config.disabled" :value="value" :key="option.value" :label="option.value" @input="input" @blur="blur">{{ option.label }}</el-radio>
    </template>
    <!-- 多选 -->
    <template v-else-if="config.type==='checkbox'">
      <el-checkbox v-for="option in config.options" v-bind="config.attribute" :disabled="config.disabled" :value="value" :key="option.value" :label="option.value" @input="input" @blur="blur">{{ option.label }}</el-checkbox>
    </template>
    <!-- 树形选择 -->
    <el-cascader
      v-else-if="config.type==='tree'"
      v-bind="config.attribute"
      :value="value"
      :disabled="config.disabled"
      :options="config.treeOptions"
      placeholder="输入搜索或者点击选择"
      size="small"
      filterable
      change-on-select
      @input="input"
      @blur="blur"/>

    <!-- 日期选择 -->
    <el-date-picker v-else-if="config.type==='date'" v-bind="config.attribute" :value="value" :placeholder="config.placeholder" :disabled="config.disabled" size="small" value-format="yyyy-MM-dd" type="date" @input="input" @blur="blur"/>
    <!-- 时间选择 -->
    <el-time-picker v-else-if="config.type==='time'" v-bind="config.attribute" :value="value" :placeholder="config.placeholder" :disabled="config.disabled" size="small" value-format="HH:mm:ss" @input="input" @blur="blur"/>
    <!-- 日期时间选择 -->
    <el-date-picker v-else-if="config.type==='dateTime'" v-bind="config.attribute" :value="value" :placeholder="config.placeholder" :disabled="config.disabled" size="small" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" @input="input" @blur="blur"/>
    <!-- 日期时间范围选择 -->
    <el-date-picker
      v-else-if="config.type==='datetimerange'"
      v-bind="config.attribute"
      :value="value"
      :disabled="config.disabled"
      type="datetimerange"
      size="small"
      range-separator="至"
      start-placeholder="开始日期"
      end-placeholder="结束日期"
      align="right"
      value-format="yyyy-MM-dd"
      @input="input"
      @blur="blur"/>
    <!-- 时间段选择 -->
    <el-time-picker
      v-else-if="config.type==='timerange'"
      v-bind="config.attribute"
      :value="value"
      :placeholder="config.placeholder"
      :disabled="config.disabled"
      size="small"
      value-format="HH:mm:ss"
      is-range
      range-separator="至"
      start-placeholder="开始时间"
      end-placeholder="结束时间"
      @input="input"
      @blur="blur"/>
    <!-- 颜色选择 -->
    <el-color-picker v-else-if="config.type==='color'" v-bind="config.attribute" :value="value" :disabled="config.disabled" @input="input" @blur="blur"/>
    <!-- 图片上传 -->
    <mlupload v-else-if="config.type==='upload'" v-bind="config.attribute" :limit="config.limit" :value="value" :disabled="config.disabled" @input="input"/>
    <!-- 百度富文本 -->
    <mleditor v-else-if="config.type==='editor'" v-bind="config.attribute" :value="value" :default-msg="config.defaultMsg" :disabled="config.disabled" @input="input" @blur="blur"/>
    <!-- 地图选择点 -->
    <mapChoose v-else-if="config.type==='mapChoose'" v-bind="config.attribute" :value="value" :config="config" :disabled="config.disabled" @input="input"/>
    <!-- 后面的标注 -->
    <span v-if="config.remark" class="remark">{{ config.remark }}</span>
  </el-form-item>
  <!-- 可增加组输入 -->
  <ojbForm
    v-else
    v-show="getShow(config.show)"
    ref="ojbFormItem"
    :required="required"
    :error="error"
    :validate-status="validateStatus"
    :config="config"
    :config-all="configAll"
    :value="value"
    :base-root-val="baseRootVal"
    :parent-val="baseThisVal"
    @input="input"/>
</template>
<script>
// import msvideo from '@/components/video/video'
// import formItem from './formItem.vue'
import mlupload from './../mlImgUpload'
import ojbForm from './ojbForm.vue'
// import mleditor from '@common/editor'
import mapChoose from './../mlMapChoose'
// import { insertStyle } from '@/utils'
import regRules from '@/filters/regRules.js'

export default {
  components: {
    mlupload,
    ojbForm,
    mapChoose
  },

  props: {
    config: {
      type: Object,
      required: true
    },
    value: {
      type: null,
      required: true
    },
    configAll: {
      type: Object,
      required: true
    },
    baseRootVal: {
      type: Object,
      required: false,
      default: null
    },
    baseParentVal: {
      type: Object,
      required: false,
      default: null
    },
    baseThisVal: {
      type: Object,
      required: false,
      default: null
    }
    // valObj:{
    //   type: Object,
    //   required: true
    // }
  },

  data() {
    // TODO  show条件判断 默认当前层级 $parent至上一层
    return {
      validateStatus: '',
      error: '',
      required: this.config.must,
      show: true,
      beforeHide: null
    }
  },

  computed: {
    rules() {
      const obj = {
        blur: [],
        input: []
      }
      if (this.config.min !== undefined && this.config.max !== undefined) {
        obj.input.push({
          pattern: new RegExp(`^{${this.config.min},${this.config.max}}$`),
          message: `输入字符长度应在 ${this.config.min} 到 ${this.config.max} 个字符`
        })
      }
      if (this.config.reg) {
        obj.input.push({
          pattern: new RegExp(this.config.reg), //  ^[\u4E00-\u9FA5]+$
          message: this.config.error
        })
      }
      if (this.config.rules && this.config.rules.length > 0) {
        for (let i = 0; i < this.config.rules.length; i++) {
          obj.input.push({
            validator: this.config.rules[i].validator,
            message: this.config.rules[i].msg || this.config.error
          })
        }
      }
      return obj
    },
    width() {
      let width = '100%'
      if (this.configAll.inline && !this.config.block) {
        width = this.configAll.inputWidth
      }
      return width
    }
  },

  created() {
    // 初始化正则验证及提示
    this.config.reg = regRules[this.config.type]
    if (!this.config.placeholder && this.config.label) {
      this.config.placeholder = `请输入${this.config.label}`
    }
    if (!this.config.error && this.config.label) {
      this.config.error = `请输入合法的${this.config.label}`
    }
    // 初始化显示条件
    if (
      !this.config.show &&
      this.config.show !== false &&
      this.config.show !== 'false'
    ) {
      this.config.show = true
    }
    // 设置块级显示
    if (this.config.block === undefined) {
      if (this.config.type === 'upload' || this.config.type === 'mapChoose' || this.config.type === 'text') {
        this.config.block = true
      }
    }
  },

  mounted() {
    if (this.configAll.labelWidth) {
      //  插入样式字符串到文档中
      // insertStyle(`.el-form--inline .el-form-item__content{ width: calc(100% - ${this.configAll.labelWidth});}`)
    }
  },

  methods: {
    input(val) {
      if (this.value === val) {
        return
      }
      this.$emit('input', val)
      this.validateInput(val)
      // this.validateStatus = 'error'
      //     this.error = 'rule.message'
      // this.validateStatus = 'success'
      // this.error = '请输入'
      // rules.input.forEach(rule => {
      //   // .test
      // })
    },
    clearValidate() {
      this.validateStatus = ''
      this.error = ''
    },
    validate() {
      return (
        this.validateInput(this.value, 'blur', true) &&
        this.validateInput(this.value, 'input', true)
      )
    },
    validateNoMsg() {
      return (
        this.validateInputNoMsg(this.value, 'blur', true) &&
        this.validateInputNoMsg(this.value, 'input', true)
      )
    },
    blur() {
      this.validateInput(this.value, 'blur') && this.validateInput(this.value)
    },
    // 只有全局调用表单验证的时候，校验object子元素否则延迟，不能返回nextTick不能返回状态，得使用回调的方式
    validateInput(val, type = 'input', validate = false) {
      if (!this.show) {
        return true
      }
      if (this.required && ((!val || val.length === 0) && val !== 0)) {
        this.validateStatus = 'error'
        this.error = `必填项${this.config.label}不能为空`
        return false
      }
      if (this.config.type === 'object' && validate) {
        return this.$refs['ojbFormItem'].validate()
      } else if (this.config.type === 'object' && !validate) {
        this.validateStatus = ''
        return true
      }
      for (var i = 0; i < this.rules[type].length; i++) {
        if (
          (this.rules[type][i].pattern && !this.rules[type][i].pattern.test(val)) ||
          (this.rules[type][i].validator && !this.rules[type][i].validator(this.baseThisVal, this.baseParentVal, this.baseRootVal))
        ) {
          this.validateStatus = 'error'
          this.error = this.rules[type][i].message
          return false
        }
      }
      this.validateStatus = 'success'
      return true
    },
    // 只有全局调用表单验证的时候，校验object子元素
    validateInputNoMsg(val, type = 'input', validate = false) {
      if (!this.show) {
        return true
      }
      if (this.required && (!val || val.length === 0)) {
        return false
      }
      if (this.config.type === 'object' && validate) {
        return this.$refs['ojbFormItem'].validateNoMsg()
      } else if (this.config.type === 'object' && !validate) {
        return true
      }
      for (var i = 0; i < this.rules[type].length; i++) {
        if (
          (this.rules[type][i].pattern && !this.rules[type][i].pattern.test(val)) ||
          (this.rules[type][i].validator && !this.rules[type][i].validator(this.baseThisVal, this.baseParentVal, this.baseRootVal))
        ) {
          return false
        }
      }
      return true
    },
    // 根据条件来显示隐藏
    // baseRootVal 通过根数据来控制
    getShow() {
      const show = this.config.show
      if (show === false || show === 'false') {
        return false
      } else if (!show || show === true || show === 'true') {
        return true
      } else if (typeof show === 'function') {
        if (show(this.baseThisVal, this.baseParentVal, this.baseRootVal)) {
          if (this.show === false) {
            this.$emit('show', this.beforeHide)
          }
          this.show = true
        } else {
          // 不显示的时候，重置值
          if (this.show === true) {
            this.beforeHide = this.value
            this.$emit('hide', this.config.key)
          }

          // if (this.config.type == "object") {
          //   if (this.value != []) {
          //     this.$emit("input", [])
          //   }
          // } else {
          //   if (this.value != null) {
          //     this.$emit("input", null)
          //   }
          // }
          this.show = false
        }
        return this.show
      }
    }

    // 规则
  }
}
</script>
<style lang="scss">
.mlform {
  .el-form-item__label{
    // color: #333;
    font-weight: normal;
  }
  &.el-form--inline{
    .mlform-item{
      margin-right: 0;
      padding-right: 10px;
    }
  }
  .el-input, .el-input__inner{
    width: 100%;
    max-width: 200px;
  }
  .mlform-item{
    display: inline-flex;
    .el-form-item__content{
      flex: 1;
    }
  }

  .ml-form-checkbox,
  .ml-form-radio {
    display: block;
    @include inline(2);
  }
  .ml-form-editor {
    .el-form-item__content {
      width: 80%;
    }
  }
  .ml-form-object {
    .el-form-item__content {
      margin-left: 0 !important;
    }
  }

  .remark {
    color: #999;
    padding-left: 20px;
  }
  .ml-form-object {
    @include inline(2);
    align-items: flex-start;
    margin-top: 20px;
  }
  .ml-form-text {
    .el-form-item__content {
      .text-input{
        max-width: 600px;
        width: 100%;
      }
    }
  }
  .ml-form-color .el-color-picker {
    float: left;
  }
  .el-color-picker__trigger {
    width: 80px;
  }
  .mlform-item-block {
    display: flex;
  }
}
</style>
